package com.ilop.siteraudio.activity;

import android.Manifest;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Looper;
import android.provider.Settings;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

import com.bumptech.glide.Glide;
import com.example.myapplication_ccc.MainActivity;
import com.ilop.siteraudio.R;
import com.ilop.siteraudio.base.BaseDialog;
import com.ilop.siteraudio.base.impl.DialogClickCallBack;
import com.ilop.siteraudio.data.bean.RecordBean;
import com.ilop.siteraudio.data.util.RecordDaoUtil;
import com.ilop.siteraudio.record.RecordConfig;
import com.ilop.siteraudio.record.RecordManager;
import com.ilop.siteraudio.util.CustomToastUtil;
import com.ilop.siteraudio.util.DateUtils;
import com.ilop.siteraudio.util.FileUtils;
import com.ilop.siteraudio.util.StatusBarUtil;
import com.ilop.siteraudio.view.TickStatusView;
import com.permissionx.guolindev.PermissionX;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import butterknife.BindView;
import butterknife.ButterKnife;

/**
 * @author skygge
 * @date 1/26/21.
 * GitHub：javofxu@github.com
 * email：skygge@yeah.net
 * description：
 */
public class TestAlarmActivity extends AppCompatActivity {

    private static final String TAG = TestAlarmActivity.class.getSimpleName();

    @SuppressLint("NonConstantResourceId")
    @BindView(R.id.iv_test_back)
    ImageView mTestBack;
    @SuppressLint("NonConstantResourceId")
    @BindView(R.id.iv_test_gif)
    ImageView mTestGif;
    @SuppressLint("NonConstantResourceId")
    @BindView(R.id.test_guide)
    LinearLayout mTestGuide;
    @SuppressLint("NonConstantResourceId")
    @BindView(R.id.test_step)
    ImageView mTestStep;
    @SuppressLint("NonConstantResourceId")
    @BindView(R.id.test_progress)
    TickStatusView mTestProgress;
    @SuppressLint("NonConstantResourceId")
    @BindView(R.id.test_inputting)
    LinearLayout mInputting;
    @SuppressLint("NonConstantResourceId")
    @BindView(R.id.test_message)
    TextView mMessage;
    @SuppressLint("NonConstantResourceId")
    @BindView(R.id.test_result)
    TextView mTestButton;

    private RecordManager mRecordManager;

    private boolean mTestResult;
    private boolean mTestFirst = true;

    private int minute = 60;
    private Timer mTimer;

    private Handler mHandler;

    private long mRecordId;
    private String mRecordPath;
    private List<Integer> mRecordFrequency;
    private List<Integer> mRecordFinish;
    private final byte[] mSuccessCode = new byte[] {0, 0, 127};

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test_alarm);
        StatusBarUtil.setDefaultStatus(this);
        ButterKnife.bind(this);
        Glide.with(this).asGif().load(R.drawable.explain_2).into(mTestGif);
        mHandler = new Handler(Looper.getMainLooper());
        mRecordFrequency = new ArrayList<>();
        mRecordFinish = new ArrayList<>();
        initPermission();
        initListener();
    }

    private void initListener() {
        mTestBack.setOnClickListener(view -> onFinish());
        mTestButton.setOnClickListener(view -> {
            if (mTestResult) {
                Intent intent = new Intent(TestAlarmActivity.this, ReportDetailActivity.class);
                intent.putExtra("recordId", mRecordId);
                startActivity(intent);
                finish();
            } else {
                mTestFirst = true;
                mRecordFrequency.clear();
                mTestGuide.setVisibility(View.VISIBLE);
                mInputting.setVisibility(View.GONE);
                onStartCountDown();
                onStartAudio();
            }
        });
    }

    /**
     * 初始化权限
     */
    public void initPermission(){
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            if (Environment.isExternalStorageManager()) {
                initAudio();
            } else {
                startActivityForResult(new Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION), 1);
            }
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            PermissionX.init(this)
                    .permissions(Manifest.permission.RECORD_AUDIO, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE)
                    .onExplainRequestReason((scope, deniedList) ->
                            scope.showRequestReasonDialog(deniedList, getString(R.string.denied_permissions), getString(R.string.confirm), getString(R.string.cancel)))
                    .onForwardToSettings((scope, deniedList) ->
                            scope.showForwardToSettingsDialog(deniedList, getString(R.string.allow_permissions), getString(R.string.confirm), getString(R.string.cancel)))
                    .request((allGranted, grantedList, deniedList) -> {
                        if (allGranted) initAudio();
                    });
        } else {
            initAudio();
        }
    }

    /**
     * 初始化录音
     * 录音配置
     */
    public void initAudio(){
        mRecordManager = RecordManager.getInstance();
        mRecordManager.init(getApplication(), true);
        mRecordManager.changeFormat(RecordConfig.RecordFormat.WAV);
        mRecordManager.changeRecordDir();
        mRecordManager.setRecordDataListener(this::onAnalysisFrequency);
        mRecordManager.setRecordResultListener(this::onGetRecordInfo);
        onStartCountDown();
        onStartAudio();
    }

    /**
     * 解析波形数据
     */
    private void onAnalysisFrequency(byte[] data) {
        try {
            int frequency = MainActivity.userAudioGet(data, data.length);
            Log.i(TAG, "onAnalysisFrequency: " + frequency);
            if (frequency > 60 && mTestFirst) {
                onShowProgress();
                mTestFirst = false;
            }
            if (frequency == 0) {
                mRecordFinish.add(0);
                if (mRecordFinish.size() > 8) {
                    if (mRecordFrequency.size() > 120) {
                        onStopAudio();
                    } else {
                        mRecordFrequency.clear();
                    }
                }
            } else {
                mRecordFrequency.add(frequency);
                mRecordFinish.clear();
            }
        }catch (Exception ignored){
            Log.e(TAG, "initAudio: 录制错误");
            onRecordFailed();
        }
    }

    /**
     * 开始录音
     */
    private void onStartAudio() {
        mRecordManager.start();
    }

    /**
     * 停止录音
     */
    private void onStopAudio() {
        if (mRecordManager != null) {
            mRecordManager.stop();
        }
        onStopCountDown();
    }

    /**
     * 正在录音
     */
    private void onShowProgress() {
        RecordManager.onStartInputRecord();
        mTestGuide.setVisibility(View.GONE);
        mInputting.setVisibility(View.VISIBLE);
        mTestStep.setVisibility(View.VISIBLE);
        mTestButton.setVisibility(View.GONE);
        mMessage.setText(getString(R.string.recording_data));
        mTestProgress.loadLoading();
    }

    /**
     * 解析音频文件
     * @param result 文件路径
     */
    private void onGetRecordInfo(File result) {
        mRecordPath = result.getAbsolutePath();
        Log.i(TAG, "onGetRecordInfo: " + mRecordPath);
        boolean isExists = FileUtils.isFileExists(mRecordPath);
        if (isExists) {
            byte[] array = MainActivity.userAudioRun(mRecordPath);
            System.out.println(Arrays.toString(array));
            try {
                byte[] results = Arrays.copyOfRange(array, 0, 3);
                System.out.println(Arrays.toString(results));
                if (Arrays.equals(mSuccessCode, results)) {
                    onStopProgress(true);
                }else {
                    onRecordFailed();
                }
            }catch (Exception e) {
                onRecordFailed();
            }
        }else {
            onRecordFailed();
        }
    }

    /**
     * 录音失败
     */
    private void onRecordFailed() {
        onStopAudio();
        onStopProgress(false);
    }

    /**
     * 录音结果
     */
    private void onStopProgress(boolean isSuccess) {
        this.mTestResult = isSuccess;
        mTestStep.setVisibility(View.INVISIBLE);
        mTestButton.setVisibility(View.VISIBLE);
        if (isSuccess) {
            mTestProgress.loadSuccess();
            mMessage.setText(getString(R.string.recording_success));
            mTestButton.setText(getString(R.string.view_test_report));
            onSaveRecordInfo();
        } else {
            mTestGuide.setVisibility(View.GONE);
            mInputting.setVisibility(View.VISIBLE);
            mTestProgress.loadFailure();
            mMessage.setText(getString(R.string.recording_failed));
            mTestButton.setText(getString(R.string.try_again));
        }
    }

    /**
     * 保存录音信息
     */
    private void onSaveRecordInfo() {
        String time = DateUtils.getDayTime();
        int position = Integer.parseInt(time.substring(0, 2));
        String[] month = getResources().getStringArray(R.array.month);
        String times = month[position-1] + time.substring(2);
        mRecordId = RecordDaoUtil.getInstance().getMaxRecordId() + 1;
        RecordBean record = new RecordBean();
        record.setRecordId(mRecordId);
        record.setTitle("GS529" + getString(R.string.report));
        record.setTime(times);
        record.setPath(mRecordPath);
        RecordDaoUtil.getInstance().getRecordDao().insert(record);
    }

    private void onFinish() {
        onStopAudio();
        finish();
    }

    private void onStartCountDown() {
        mTimer = new Timer();
        TimerTask timerTask = new TimerTask() {
            @Override
            public void run() {
                mHandler.post(()-> {
                    minute--;
                    if (minute == 0) {
                        onRecordFailed();
                    }
                });
            }
        };
        mTimer.schedule(timerTask, 0,1000);
    }

    private void onStopCountDown() {
        if (mTimer != null){
            mTimer.cancel();
            mTimer = null;
            minute = 60;
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == 1 && Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            if (Environment.isExternalStorageManager()) {
                initAudio();
            } else {
                BaseDialog mDialog = new BaseDialog(this, new DialogClickCallBack(){
                    @Override
                    public void onConfirm() {
                        super.onConfirm();
                        startActivityForResult(new Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION), 1);
                    }

                    @Override
                    public void onCancel() {
                        super.onCancel();
                        CustomToastUtil.showToast(TestAlarmActivity.this, R.string.denied_permissions);
                    }
                });
                mDialog.setTitleAndButton(getString(R.string.denied_permissions), getString(R.string.cancel), getString(R.string.go_set));
                mDialog.show();
            }
        }
    }

    @Override
    public void onBackPressed() {
        onFinish();
    }
}
